﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Clipping.Infrastructure.Models;
using System.Web;
using System.Text.RegularExpressions;

namespace Clipping.Utils.SearchEngines
{
    public class ZhongsouNews : ISearchEngine
    {
        private Encoding _urlEncoding = Encoding.GetEncoding("gb2312");
        private Encoding _contentEncoding = Encoding.GetEncoding("gb2312");

        public void Parse(Uri url, string html, out List<News> news, out string nextPageUrl)
        {
            parse(html, out news, out nextPageUrl);
            if (!string.IsNullOrEmpty(nextPageUrl))
                nextPageUrl = constructAbsoluteUrl(url, nextPageUrl).OriginalString;
            if (news != null)
            {
                foreach (var n in news)
                {
                    if (!string.IsNullOrEmpty(n.SameNewsUrl))
                        n.SameNewsUrl = constructAbsoluteUrl(url, n.SameNewsUrl).OriginalString;
                }
            }
        }

        public Uri ConstructUrl(SearchObject searchObj)
        {
            return constructUrl(searchObj);
        }
        public void Search(Infrastructure.Models.SearchObject searchObj, IHtmlDownload downloader, out List<Infrastructure.Models.News> news, out string nextPageUrl)
        {
            var url = constructUrl(searchObj);
            string html = downloader.GetHtml(url);
            parse(html, out news, out nextPageUrl);
            if (!string.IsNullOrEmpty(nextPageUrl))
                nextPageUrl = constructAbsoluteUrl(url, nextPageUrl).OriginalString;
            if (news != null)
            {
                foreach (var n in news)
                {
                    if (!string.IsNullOrEmpty(n.SameNewsUrl))
                        n.SameNewsUrl = constructAbsoluteUrl(url, n.SameNewsUrl).OriginalString;
                }
            }
        }



        #region 私有方法

        private Uri constructUrl(Infrastructure.Models.SearchObject searchObj)
        {
            //Contract.Requires(searchObj != null);
            if (searchObj.SearchType == SearchType.SearchInTitle)
            {
                return new Uri(string.Format("{0}{1}{2}", "http://z.zhongsou.com/n?w=", HttpUtility.UrlEncode(searchObj.Keyword, this._urlEncoding), "&t=1"));
            }
            else
            {
                return new Uri(string.Format("{0}{1}{2}", "http://z.zhongsou.com/n?w=", HttpUtility.UrlEncode(searchObj.Keyword, this._urlEncoding), "&t=0"));
            }
        }

        private Uri constructAbsoluteUrl(Uri baseUri, string url)
        {
            return UriHelper.ConstructAbsoluteUrl(baseUri, url);
        }

        private void parse(string html, out List<Infrastructure.Models.News> news, out string nextPageUrl)
        {
            news = new List<News>();
            nextPageUrl = null;
            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(html);
            var liNav = doc.CreateNavigator();


            //对全文搜索结果的提取
            var divSearchResult = liNav.Select("//li[@class='clearfix']");

            while (divSearchResult.MoveNext())
            {
                News n = new News();

                var li = divSearchResult.Current;
                //取标题和链接
                var linkNode = li.SelectSingleNode("descendant::h3[@class='h3-zx']/a");
                if (linkNode != null)
                {
                    n.Title = System.Web.HttpUtility.HtmlDecode(linkNode.Value);
                    n.Url = linkNode.GetAttribute("href", "");
                }

                //取媒体和时间
                var mediaAndTimeNode = li.SelectSingleNode("descendant::nobr");

                if (mediaAndTimeNode != null)
                {

                    string mt = mediaAndTimeNode.Value;
                    if (!string.IsNullOrEmpty(mt))
                    {

                        mt = System.Web.HttpUtility.HtmlDecode(mt);
                        mt = mt.Trim();
                        int spaceIndex = System.Text.RegularExpressions.Regex.Match(mt, @"\s").Index;
                        if (spaceIndex > 0)
                        {
                            n.Media = mt.Substring(0, spaceIndex);
                            n.PubDate = mt.Substring(spaceIndex + 1);
                        }
                    }
                }






                //取摘要
                var summaryNode = li.SelectSingleNode("descendant::div[@class='img-info clearfix']");
                if (summaryNode != null)
                {
                    n.Summary = System.Web.HttpUtility.HtmlDecode(summaryNode.Value);
                }

                //取相同新闻
                var sameNewsUrlNode = li.SelectSingleNode("descendant::span[@class='zx-news']/a");
                if (sameNewsUrlNode != null)
                {
                    n.SameNewsUrl = System.Web.HttpUtility.HtmlDecode(sameNewsUrlNode.GetAttribute("href", ""));
                }
                news.Add(n);

            }


            //对标题搜索结果的提取
            divSearchResult = liNav.Select("//ul[@class='maintit_s mtop10_s']");
            while (divSearchResult.MoveNext())
            {
                News n = new News();
                var li = divSearchResult.Current;
                //取标题和链接
                var linkNode = li.SelectSingleNode("descendant::a");
                if (linkNode != null)
                {
                    n.Title = System.Web.HttpUtility.HtmlDecode(linkNode.Value);
                    n.Url = System.Web.HttpUtility.UrlDecode(linkNode.GetAttribute("href", ""));
                }

                var mediaAndTimeNode = li.SelectSingleNode("descendant::span");
                Match match = Regex.Match(mediaAndTimeNode.Value, @"(?<media>[^\s]+)\s+(?<date>[1-2][0-9]{3}/[0-2][0-9]/[0-3][0-9])\s+(?<time>[0-2][0-9]:[0-6][0-9])", RegexOptions.None);
                if (match.Success)
                {
                    n.Media = System.Web.HttpUtility.HtmlDecode(match.Groups["media"].Value);
                    n.PubDate = string.Format("{0} {1}", match.Groups["date"].Value, match.Groups["time"].Value);
                }

                news.Add(n);
            }







            //取下一页地址
            var pageNodes = liNav.Select("//div[@class='page']/descendant::a");
            while (pageNodes.MoveNext())
            {
                var pageNode = pageNodes.Current;
                if (!string.IsNullOrEmpty(pageNode.Value) && pageNode.Value.Contains("下一页"))
                {
                    nextPageUrl = pageNode.GetAttribute("href", "");
                    break;
                }

            }


        }

        #endregion


        #region 属性
        public string Name
        {
            get { return "中搜新闻搜索"; }
        }
        public Encoding ContentEncoding
        {
            get { return _contentEncoding; }
        }
        #endregion



    }
}
